package com.xiaotao.graphql.dataloader;

import com.netflix.graphql.dgs.DgsDataLoader;
import com.xiaotao.graphql.pojo.Phone;
import com.xiaotao.graphql.pojo.User;
import lombok.extern.slf4j.Slf4j;
import org.dataloader.BatchLoader;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.stream.Collectors;

/**
 * @author xiaotao
 */
@Slf4j
@DgsDataLoader(name = "userPhoneListuserPhoneList")
public class PhoneDataLoader implements BatchLoader<String, List<Phone>> {

    /**
     * 用户列表集合
     */
    public static List<User> userList = new ArrayList<>();

    /**
     * 手机列表集合
     */
    public static List<Phone> phoneList = new ArrayList<>();
    static{

        //初始化用户列表集合
        User user1 = new User();
        user1.setUserId("zhangsan");
        user1.setUserName("张三");
        userList.add(user1);

        User user2 = new User();
        user2.setUserId("lisi");
        user2.setUserName("李四");
        userList.add(user2);

        //初始化手机列表集合
        Phone phone1 = new Phone();
        phone1.setPhoneId("huawei");
        phone1.setPhoneName("华为");
        phone1.setUserId("zhangsan");
        phoneList.add(phone1);

        Phone phone2 = new Phone();
        phone2.setPhoneId("xiaomi");
        phone2.setPhoneName("小米");
        phone2.setUserId("zhangsan");
        phoneList.add(phone2);

        Phone phone3 = new Phone();
        phone3.setPhoneId("hongmi");
        phone3.setPhoneName("红米");
        phone3.setUserId("lisi");
        phoneList.add(phone3);
    }

    /**
     * 两个List嵌套：第一个list为graphql的单个对象到多个对象的转换，第二个list为用户和手机的一对多关系。
     * dgs会把用户id收集起来，一把调用数据库。实现的时候是集合出入参，调用的时候是单个出入参，dgs框架会完成单个和集合的转换。
     * @param list
     * @return
     */
    @Override
    public CompletionStage<List<List<Phone>>> load(List<String> list) {
        return CompletableFuture.supplyAsync(() -> this.getPhoneInfo(list));
    }

    /**
     * 转化一对多的关系
     * @param list
     * @return
     */
    private List<List<Phone>> getPhoneInfo(List<String> list){

        log.debug("3-异步获取用户的手机方法被执行");
        List<Phone> phones = new ArrayList<>();
        List<List<Phone>> resultList = new ArrayList<>();
        for(Phone a :phoneList){
            for(String b:list){
                if(a.getUserId().equals(b)){
                    phones.add(a);
                }
            }
        }
        Map<String, List<Phone>> map = phones.stream().collect(Collectors.groupingBy(Phone::getUserId));

        for(String a: map.keySet()){
            if(map.containsKey(a)){
                List<Phone> phone = map.get(a);
                resultList.add(phone);
            }
        }

        return resultList;

    }
}
